var shortNameAllowedSymbolsClass = '0-9a-z!#$;=[\\]_~-';
var shortNamePattern = new RegExp('^[' + shortNameAllowedSymbolsClass + ']+$', 'i');

var preReplaceRegExp = new RegExp('[^' + shortNameAllowedSymbolsClass + ']{2,}', 'ig');
var replaceRegExp = new RegExp('[^' + shortNameAllowedSymbolsClass + ']{1,}', 'ig');

var validator = function (element) {
    return $(element).valid();
};

var highlighter = function (element) {
    element = element instanceof jQuery ? element : $(element);
    element.closest('.control-group').removeClass('success').addClass('error');
};

var unhighlighter = function (element) {
    element = element instanceof jQuery ? element : $(element);
    element.closest('.control-group').removeClass('error').addClass('success');
};

var errorPlacer = function (error, element) {
    element = element instanceof jQuery ? element : $(element);
    error = typeof error == 'string' ? error : error.text();
    $('label[for="' + element.attr('id') + '"].help-inline').text(error);
};

function handleViolations(response) {
    $.each(response.violations, function(key, value) {
        var element = $('[path="' + value.property + '"]');
        highlighter(element);
        errorPlacer(value.message, element);
    });
}

$.validator.addMethod('svnUrl', function (value, element) {
    return this.optional(element) || /^(https?|svn(\+ssh)?):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
});

$.extend($.validator.messages, {
    required: 'This field is required',
    maxlength: 'Field is too long',
    remote: 'This name is busy',
    pattern: 'Invalid symbols',
    min: 'Must be lesser then or equal to ${0}',
    max: 'Must be greater then or equal to ${0}',
    svnUrl: 'URL is invalid'
});

$.validator.setDefaults({
    success: function () {},
    errorPlacement: errorPlacer,
    highlight: highlighter,
    unhighlight: unhighlighter
});